package com.cloudkinto.service.orderinput.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.common.DicBusinessConstant;
import com.cloudkinto.common.DicBusinessItemConstant;
import com.cloudkinto.common.constant.GlobalConstants;
import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.error.ErrorEnum;
import com.cloudkinto.common.exception.BizExceptionI18;
import com.cloudkinto.common.exception.NotSufficientFundsException;
import com.cloudkinto.common.utils.*;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;
import com.cloudkinto.dao.*;
import com.cloudkinto.entity.*;
import com.cloudkinto.extentity.product.ProductSkuAndIdDto;
import com.cloudkinto.service.dic.DicBusinessItemService;
import com.cloudkinto.service.dic.vo.DicItemRes;
import com.cloudkinto.service.dic.vo.LanguageValueEntity;
import com.cloudkinto.service.email.MailSenderService;
import com.cloudkinto.service.fbaorderoutput.vo.FbaOrderOutputPackageUpdateReq;
import com.cloudkinto.service.fbaorderoutput.vo.FbaOrderOutputProductDetail;
import com.cloudkinto.service.file.FileService;
import com.cloudkinto.service.finance.CompanyAccountService;
import com.cloudkinto.service.finance.CostRecordService;
import com.cloudkinto.service.headercontainer.vo.HeaderContainerProjectRes;
import com.cloudkinto.service.operate.OperateRecordService;
import com.cloudkinto.service.operate.vo.OperateRes;
import com.cloudkinto.service.orderinput.OrderInputService;
import com.cloudkinto.service.orderinput.vo.*;
import com.cloudkinto.service.orderoutput.OrderOutputService;
import com.cloudkinto.service.shop.ShopService;
import com.cloudkinto.service.stock.StockLogService;
import com.cloudkinto.service.stock.StockRecordService;
import com.cloudkinto.service.stock.vo.record.StockRecordPageRes;
import com.cloudkinto.service.storage.StorageService;
import com.cloudkinto.utils.BarCodePdfUtils;
import com.cloudkinto.utils.PdfUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * service实现类
 * </p>
 *
 * @author 张永远
 * @since 2020-06-08
 */
@Service
@Transactional(rollbackFor = Exception.class)//事务回滚
public class OrderInputServiceImpl extends ServiceImpl<OrderInputDao, OrderInputDo> implements OrderInputService {
    @Autowired
    private OrderInputDao dao;
    @Autowired
    private StorageService storageService;
    @Autowired
    private FileService fileService;
    @Autowired
    private OrderInputPackageDao orderInputPackageDao;
    @Autowired
    private OrderInputProductDao orderInputProductDao;
    @Autowired
    private ShopDao shopDao;
    @Autowired
    private StorageDao storageDao;
    @Autowired
    private ProductInfoDao productInfoDao;
    @Autowired
    private CompanyDao companyDao;
    @Autowired
    private DicBusinessItemDao dicBusinessItemDao;
    @Autowired
    private DicBusinessItemService dicBusinessItemService;
    @Autowired
    private DicBusinessDao dicBusinessDao;
    @Autowired
    private ShopService shopService;
    @Autowired
    private OperateRecordService operateRecordDao;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Autowired
    private UserDao userDao;
    @Autowired
    private CompanyAccountService companyAccountService;
    @Autowired
    private OrderOutputService orderOutputService;
    @Autowired
    private FbaStorageDao fbaStorageDao;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ThreadPoolTaskExecutor executor;
//    @Autowired
//    private ProductStockDao productStockDao;
//    @Autowired
//    private ProductOutService productOutService;
//    @Autowired
//    private ProductOutRecordDao productOutRecordDao;
//    @Autowired
//    private ProductStockRackDao productStockRackDao;
//    @Autowired
//    private StorageShelfDao storageShelfDao;
//    @Autowired
//    private StoragePositionDao storagePositionDao;
//    @Autowired
//    private ProductStockFlowingDao productStockFlowingDao;
//    @Autowired

    //真正的存储路径
    @Value("${gbc.uploadPath.filePath}")
    private String filePath;
    @Autowired
    private MailSenderService mailSenderService;
    @Autowired
    private StockRecordDao stockRecordDao;
    @Autowired
    private StockLogService stockLogService;
    @Autowired
    private StorageServiceProjectDao storageServiceDao;
    @Autowired
    private HeaderContainerDao headerContainerDao;
    @Autowired
    private ManageBillDao manageBillDao;
    @Autowired
    private HeaderContainerOrderDao headerContainerOrderDao;
    @Autowired
    private ManageHeaderPriceItemDao manageHeaderPriceItemDao;
    @Autowired
    private ManageHeaderRateDao manageHeaderRateDao;
    @Autowired
    private CostRecordService costService;
    @Autowired
    private CountryCodeDao countryDao;
    @Autowired
    private OrderInputExpireDao orderInputExpireDao;
    @Autowired
    private StockRecordService stockRecordService;

    @Override
    public SingleResult addInit(Long userId, Long companyId) {
        Map<String, List> listMap = new HashMap<>();
        List<Map> storageList = storageService.storageList();
        listMap.put("storage", storageList);
        listMap.put("shop", shopService.selectShopListInit(userId, companyId));

        //运输方式
        List<Map> transportTypeList = new ArrayList<>();
        List<Map> fbaStorageList = new ArrayList<>();
        LambdaQueryWrapper<DicBusinessItemDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DicBusinessItemDo::getDicBusinessId, DicBusinessConstant.transportType);
        List<DicBusinessItemDo> transportType = dicBusinessItemDao.selectList(wrapper);
        if (!CollectionUtils.isEmpty(transportType)) {
            transportType.forEach(e -> {
                Map map = new HashMap();
                map.put("id", e.getId());
                map.put("value", e.getDicItemValue());
                transportTypeList.add(map);
            });
        }
        listMap.put("transportTypeList", transportTypeList);

        //发货方式
        List<Map> sendOutTypeList = new ArrayList<>();
        wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DicBusinessItemDo::getDicBusinessId, DicBusinessConstant.sendOutType);
        List<DicBusinessItemDo> sendOutType = dicBusinessItemDao.selectList(wrapper);
        if (!CollectionUtils.isEmpty(sendOutType)) {
            sendOutType.forEach(e -> {
                Map map = new HashMap();
                map.put("id", e.getId());
                map.put("value", e.getDicItemValue());
                sendOutTypeList.add(map);
            });
        }
        List<FbaStorageDo> fbaStorageDoList = fbaStorageDao.selectList(null);
        fbaStorageDoList.forEach(fbaStorageDo -> {
            Map map = new HashMap();
            map.put("id", fbaStorageDo.getId());
            map.put("value", fbaStorageDo.getFbaCode());
            fbaStorageList.add(map);
        });
        listMap.put("sendOutTypeList", sendOutTypeList);
        listMap.put("fbaStorageList", fbaStorageList);
        listMap.put("countryList", countryDao.selectList(null));
        return SingleResult.success(listMap);
    }

    @Override
    public OrderInputAddReq add(OrderInputAddReq req, Long userId, Long companyId) {
        //校验余额不足
//        sufficientFundsCheck(companyId);

        OrderInputDo entityDo = new OrderInputDo();
        BeanUtils.copyProperties(req, entityDo);
        entityDo.setCompanyId(companyId);
        entityDo.setStatus(DicBusinessItemConstant.inCreateState);
        if (req.getFbaTurn() == 1) {
            //操作附件
            fileService.uploadFile(req.getFbaFileId());
        }
        if (req.getSendType() == 1) {
            //操作附件
            fileService.uploadFile(req.getClearFileId());
        }
        handlerAddBefore(entityDo, userId);
        dao.insert(entityDo);

        //操作日志
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_CREATE_INPUT, entityDo.getId(), userId, 2);
//        addOperateRecord(entityDo, userId);

        double volume = 0F;
        double weight = 0F;

        if (!CollectionUtils.isEmpty(req.getPackageList())) {
            for (OrderInputPackageAdd packageAdd : req.getPackageList()) {
                OrderInputPackageDo packageDo = new OrderInputPackageDo();
                packageDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                packageDo.setPackageLenght(packageAdd.getPackageLenght());
                packageDo.setPackageWidth(packageAdd.getPackageWidth());
                packageDo.setPackageHeight(packageAdd.getPackageHeight());
                packageDo.setPackageWeight(packageAdd.getPackageWeight());
                packageDo.setPackageCount(packageAdd.getPackageCount());
                packageDo.setBoxTypeNumber(packageAdd.getBoxTypeNumber());
                packageDo.setOrderInputId(entityDo.getId());
                orderInputPackageDao.insert(packageDo);
                if (!CollectionUtils.isEmpty(packageAdd.getProductDetailList())) {
                    for (OrderInputProductAdd productAdd : packageAdd.getProductDetailList()) {
                        if (productAdd.getProductId() == null || productAdd.getProductId() == 0) {
                            if (StringUtils.isBlank(productAdd.getProductSku())) {
                                throw new BizExceptionI18(SysConstant.NO_SKU_PLS_CHECK);
                            }
                            productAdd.setProductId(getProductId(productAdd.getProductSku(), companyId));
                        }
                        OrderInputProductDo productDo = new OrderInputProductDo();
                        productDo.setOrderInputId(entityDo.getId());
                        productDo.setPackageId(packageDo.getId());
                        productDo.setProductId(productAdd.getProductId());
                        productDo.setCount(productAdd.getCount());
                        orderInputProductDao.insert(productDo);
                        ProductInfoDo productInfoDo = productInfoDao.selectById(productDo.getProductId());
                        if (productInfoDo != null) {
                            volume += productInfoDo.getHeight() * productInfoDo.getWidth() * productInfoDo.getLength() * productDo.getCount() * packageDo.getPackageCount();
                            weight += productInfoDo.getWeight() * productDo.getCount() * packageDo.getPackageCount();
                        }
                    }
                } else {
                    volume += packageDo.getPackageLenght() * packageDo.getPackageWidth() * packageDo.getPackageHeight() * packageDo.getPackageCount();
                    weight += packageDo.getPackageWeight() * packageDo.getPackageCount();
                }
            }
            if (req.getProductExpireList() != null) {
                for (OrderInputProductExpireReq expireReq : req.getProductExpireList()) {
                    OrderInputExpireDo expireDo = new OrderInputExpireDo();
                    expireDo.setOrderId(entityDo.getId());
                    expireDo.setExpireTime(expireReq.getExpireTime());
                    expireDo.setCommoditySku(expireReq.getCommoditySku());
                    expireDo.setProductId(expireReq.getProductId());
                    expireDo.setCount(expireReq.getCount());
                    orderInputExpireDao.insert(expireDo);
                }
            }
        }
        entityDo.setVolume(new BigDecimal(volume / 1000000).setScale(2, RoundingMode.HALF_UP).floatValue());
        entityDo.setWeight(new BigDecimal(weight).setScale(2, RoundingMode.HALF_UP).floatValue());
        String companyCode = "";
        CompanyDo companyDo = companyDao.selectById(companyId);
        if (companyDo != null)
            companyCode = companyDo.getCompanyCode();
        entityDo.setOrderInputNumber(OrderCodeUtil.getOrderInputNumber(companyCode, entityDo.getId()));
        dao.updateById(entityDo);
//        threadPoolTaskExecutor.execute(() -> {
//            mailSenderService.sendEmail("您有新的入库申请单需要审核", entityDo.getCompanyId() +
//                    "申请了入库单，请尽快审核,备注：" + entityDo.getTips(), SysConstant.cloudkintEmail);
//        });
        return req;
    }


    private Long getProductId(String sellerSku1, Long companyId) {
        final String sellerSku = sellerSku1.trim().replaceAll("\\n", "").replaceAll("　", "");
        LambdaQueryWrapper<ProductInfoDo> productWrapper = new LambdaQueryWrapper();
        productWrapper.eq(ProductInfoDo::getCompanyId, companyId);
        productWrapper.and(product -> {
            product.eq(ProductInfoDo::getCommoditySku, sellerSku).or()
                    .eq(ProductInfoDo::getStorageSku, sellerSku);
        });
        ProductInfoDo productInfoDo = productInfoDao.selectOne(productWrapper);
        if (productInfoDo == null) {
            throw new BizExceptionI18(SysConstant.NO_PRODUCT_INFO, sellerSku);
        } else {
            return productInfoDo.getId();
        }
    }

    private void sufficientFundsCheck(Long companyId) {
        if (!companyAccountService.getIsDue(companyId)) {
            throw new NotSufficientFundsException(ErrorEnum.NOT_SUFFICIENT_FUNDS);
        }
    }
//
//    private void addOperateRecord(OrderInputDo entityDo, Long userId) {
//        OperateRecordDo operateRecordDo = new OperateRecordDo();
//        operateRecordDo.setThirdId(entityDo.getId());
//        operateRecordDo.setContent("创建了一条入库单");
//        operateRecordDo.setOperateTime(new Date());
//        operateRecordDo.setOperateBy(userId);
//        operateRecordDo.setType(2);
//        operateRecordDo.setDeleteFlag(0);
//
//        operateRecordDao.insert(operateRecordDo);
//    }

    //新增校验
    private void addCheck(Object req) {

    }

    //做新增之前要执行的业务定制处理
    private void handlerAddBefore(OrderInputDo entityDo, Long userId) {
        entityDo.setCreateBy(userId);
        entityDo.setCreateTime(new Date());
        entityDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
    }

    //将新增的do转换成要返回的实体
    private Object handlerAddAfter(OrderInputDo entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public SingleResult<Map> updateInit(Long id, Long currentUserId, Long companyId) {
        Map map = (Map) addInit(currentUserId, companyId).getData();

        OrderInputDo entityDo = dao.selectById(id);
        OderInputDetailRes res = new OderInputDetailRes();
        if (entityDo.getStatus() >= DicBusinessItemConstant.inPutStorage)
            throw new BizExceptionI18(SysConstant.NO_EDIT_ORDER_HAS_INPUT);
        ShopDo shopDo = shopDao.selectById(entityDo.getShopId());
        if (shopDo != null) {
            res.setShopName(shopDo.getShopName());
        }
        res.setExpireTime(entityDo.getExpireTime());
        res.setShopId(entityDo.getShopId());
        res.setStorageId(entityDo.getStorageId());
        res.setFbaStorageId(entityDo.getFbaStorageId());
        StorageDo storageDo = storageDao.selectById(entityDo.getStorageId());
        if (storageDo != null) {
            res.setStorage(storageDo.getStorageName());
        }
        FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(entityDo.getFbaStorageId());
        if (fbaStorageDo != null) {
            res.setFbaStorage(fbaStorageDo.getFbaCode());
        }
        res.setId(entityDo.getId());
        res.setOrderInputNumber(entityDo.getOrderInputNumber());
        res.setDeliveryDate(entityDo.getDeliveryDate());
        res.setCarriageTrackNo(entityDo.getCarriageTrackNo());
        res.setCarriageType(entityDo.getCarriageType());
        String carriageTypeItemDo = getInitValueMap().get("carriageType").get(entityDo.getCarriageType().intValue());
        if (carriageTypeItemDo != null) {
            res.setCarriageTypeName(carriageTypeItemDo);
        }
        res.setSendType(entityDo.getSendType());
//        DicBusinessItemDo sendtypeItemDo = dicBusinessItemDao.selectById(entityDo.getSendType());
        String sendtypeItemDo = getInitValueMap().get("sendType").get(entityDo.getSendType().intValue());
        if (sendtypeItemDo != null) {
            res.setSendTypeName(sendtypeItemDo);
        }
        res.setCarriageTrackNo(entityDo.getCarriageTrackNo());
        res.setFbaTurn(entityDo.getFbaTurn());
        res.setCountryName(entityDo.getCountryName());
        DicBusinessItemDo businessItemDo = dicBusinessItemDao.selectById(entityDo.getStatus());
        if (businessItemDo != null) {
            res.setStatus(businessItemDo.getDicItemValue());
        }
        res.setStatusId(entityDo.getStatus());
        res.setFbaNo(entityDo.getFbaNo());
        res.setFbaPo(entityDo.getFbaPo());
        res.setFbaFileUrl(fileService.getFilePath(entityDo.getFbaFileId()));
        res.setClearFileUrl(fileService.getFilePath(entityDo.getClearFileId()));
        res.setFbaFileId(entityDo.getFbaFileId());
        res.setClearFileId(entityDo.getClearFileId());
        FileDo fileDo = fileService.getBaseMapper().selectById(entityDo.getFbaFileId());
        if (fileDo != null) {
            res.setFileName(fileDo.getFileName());
        }
        res.setVolume(entityDo.getVolume());
        res.setTips(entityDo.getTips());
        res.setSeaFee(entityDo.getSeaFee());
        res.setClearanceFee(entityDo.getClearanceFee());
        res.setServiceFee(entityDo.getServiceFee());
        res.setTaxFee(entityDo.getTaxFee());
        List<OrderInputPackageDetail> packageList = new ArrayList<>();
        LambdaQueryWrapper<OrderInputPackageDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderInputPackageDo::getOrderInputId, entityDo.getId());
        List<OrderInputPackageDo> orderInputPackageDos = orderInputPackageDao.selectList(wrapper);
        if (!CollectionUtils.isEmpty(orderInputPackageDos)) {
            for (OrderInputPackageDo packageDo : orderInputPackageDos) {
                OrderInputPackageDetail packageDetail = new OrderInputPackageDetail();
                packageDetail.setId(packageDo.getId());
                packageDetail.setCount(packageDo.getPackageCount());
                packageDetail.setHeight(packageDo.getPackageHeight());
                packageDetail.setLength(packageDo.getPackageLenght());
                packageDetail.setWeight(packageDo.getPackageWeight());
                packageDetail.setWidth(packageDo.getPackageWidth());
                packageDetail.setBoxTypeNumber(packageDo.getBoxTypeNumber());
                List<OrderInputProductDetail> productAddList = new ArrayList<>();

                LambdaQueryWrapper<OrderInputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                productDoLambdaQueryWrapper.eq(OrderInputProductDo::getOrderInputId, entityDo.getId()).eq(OrderInputProductDo::getPackageId, packageDo.getId());
                List<OrderInputProductDo> orderInputProductDos = orderInputProductDao.selectList(productDoLambdaQueryWrapper);
                if (!CollectionUtils.isEmpty(orderInputProductDos)) {
                    for (OrderInputProductDo productDo : orderInputProductDos) {
                        OrderInputProductDetail productDetail = new OrderInputProductDetail();
                        ProductInfoDo productInfoDo = productInfoDao.selectById(productDo.getProductId());
                        if (productInfoDo != null) {
                            productDetail.setProductId(productInfoDo.getId());
                            productDetail.setCount(productDo.getCount());
                            productDetail.setCommoditySku(productInfoDo.getCommoditySku());
                            productDetail.setProductName(productInfoDo.getProductName());
                            productDetail.setStorageSku(productInfoDo.getStorageSku());
                            productAddList.add(productDetail);
                        }
                    }
                }
                packageDetail.setProductList(productAddList);

                packageList.add(packageDetail);

            }
        }

        res.setPackageList(packageList);

        //查询日志
        List<OperateRes> operateResList = operateRecordDao.getOperateList(id, 2);
        res.setOperateResList(operateResList);
        //有效期
        List<OrderInputExpireDo> expireDoList = orderInputExpireDao.selectList(new LambdaQueryWrapper<OrderInputExpireDo>()
                .eq(OrderInputExpireDo::getOrderId, id));
        List<OrderInputProductExpireRes> resList = new ArrayList<>();
        for (OrderInputExpireDo expireDo : expireDoList) {
            OrderInputProductExpireRes expireRes = new OrderInputProductExpireRes();
            BeanUtils.copyProperties(expireDo, expireRes);
            resList.add(expireRes);
        }
        res.setProductExpireList(resList);
        map.put("detail", res);

        return SingleResult.success(map);
    }

    @Override
    public OrderInputUpdateReq update(OrderInputUpdateReq req, Long userId) {
        OrderInputDo entityDo = dao.selectById(req.getId());
        if (entityDo.getStatus() >= DicBusinessItemConstant.inPutStorage) {
            throw new BizExceptionI18(SysConstant.NO_EDIT_ORDER_HAS_INPUT);
        }
        if (req.getFbaFileId() == null) req.setFbaFileId(0L);
        if (entityDo.getFbaFileId() == null) entityDo.setFbaFileId(0L);
        try {
            if (req.getFbaTurn() == 1 && !req.getFbaFileId().equals(entityDo.getFbaFileId())) {
                fileService.deleteFile(entityDo.getFbaFileId());
                fileService.uploadFile2(req.getFbaFileId(), entityDo.getFbaFileId());
            }
            if (req.getSendType() == 1 && !req.getClearFileId().equals(entityDo.getClearFileId())) {
                fileService.deleteFile(entityDo.getClearFileId());
                fileService.uploadFile2(req.getClearFileId(), entityDo.getClearFileId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        BeanUtils.copyProperties(req, entityDo);
        handlerUpdateBefore(entityDo, userId);
        dao.updateById(entityDo);

        LambdaQueryWrapper<OrderInputPackageDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderInputPackageDo::getOrderInputId, entityDo.getId());
        orderInputPackageDao.delete(wrapper);

        LambdaQueryWrapper<OrderInputProductDo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(OrderInputProductDo::getOrderInputId, entityDo.getId());
        orderInputProductDao.delete(productWrapper);
        orderInputExpireDao.delete(new LambdaQueryWrapper<OrderInputExpireDo>().eq(OrderInputExpireDo::getOrderId, entityDo.getId()));

        float volume = 0F;
        float weight = 0F;

        if (!CollectionUtils.isEmpty(req.getPackageList())) {
            for (OrderInputPackageAdd packageAdd : req.getPackageList()) {
                OrderInputPackageDo packageDo = new OrderInputPackageDo();
                packageDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                packageDo.setPackageLenght(packageAdd.getPackageLenght());
                packageDo.setPackageWidth(packageAdd.getPackageWidth());
                packageDo.setPackageHeight(packageAdd.getPackageHeight());
                packageDo.setPackageWeight(packageAdd.getPackageWeight());
                packageDo.setPackageCount(packageAdd.getPackageCount());
                packageDo.setBoxTypeNumber(packageAdd.getBoxTypeNumber());
                packageDo.setOrderInputId(entityDo.getId());
                orderInputPackageDao.insert(packageDo);

                if (!CollectionUtils.isEmpty(packageAdd.getProductList())) {
                    for (OrderInputProductAdd productAdd : packageAdd.getProductList()) {
                        OrderInputProductDo productDo = new OrderInputProductDo();
                        productDo.setOrderInputId(entityDo.getId());
                        productDo.setPackageId(packageDo.getId());
                        if (productAdd.getProductId() == null || productAdd.getProductId() == 0) {
                            if (StringUtils.isBlank(productAdd.getProductSku())) {
                                throw new BizExceptionI18(SysConstant.NO_SKU_PLS_CHECK);

                            }
                            productAdd.setProductId(getProductId(productAdd.getProductSku(), entityDo.getCompanyId()));
                        }
                        productDo.setProductId(productAdd.getProductId());
                        productDo.setCount(productAdd.getCount());
                        orderInputProductDao.insert(productDo);

                        ProductInfoDo productInfoDo = productInfoDao.selectById(productDo.getProductId());
                        if (productInfoDo != null) {
                            volume += productInfoDo.getHeight() * productInfoDo.getWidth() * productInfoDo.getLength() * productDo.getCount() * packageDo.getPackageCount();
                            weight += productInfoDo.getWeight() * productDo.getCount() * packageDo.getPackageCount();
                        }

                    }
                } else {
                    volume += packageDo.getPackageLenght() * packageDo.getPackageWidth() * packageDo.getPackageHeight() * packageDo.getPackageCount();
                    weight += packageDo.getPackageWeight() * packageDo.getPackageCount();
                }
            }
            if (req.getProductExpireList() != null) {
                for (OrderInputProductExpireReq expireReq : req.getProductExpireList()) {
                    OrderInputExpireDo expireDo = new OrderInputExpireDo();
                    expireDo.setOrderId(entityDo.getId());
                    expireDo.setExpireTime(expireReq.getExpireTime());
                    expireDo.setCommoditySku(expireReq.getCommoditySku());
                    expireDo.setProductId(expireReq.getProductId());
                    expireDo.setCount(expireReq.getCount());
                    orderInputExpireDao.insert(expireDo);
                }
            }
        }
        entityDo.setVolume(new BigDecimal(volume / 1000000).setScale(2, BigDecimal.ROUND_HALF_UP).floatValue());
        entityDo.setWeight(new BigDecimal(weight).setScale(2, BigDecimal.ROUND_HALF_UP).floatValue());
        dao.updateById(entityDo);
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_UPDATE_INPUT_ORDER, entityDo.getId(), userId, 2);
//        operateRecord(req, userId);
        return req;
    }
//
//    private void operateRecord(OrderInputUpdateReq req, Long userId) {
//        OderInputDetailRes res = (OderInputDetailRes) updateInit(req.getId(), userId, null).getData().get("detail");
//        OperateRecordDo operateRecordDo = new OperateRecordDo();
//        operateRecordDo.setDeleteFlag(0);
//        operateRecordDo.setThirdId(req.getId());
//        operateRecordDo.setType(2);
//        operateRecordDo.setOperateBy(userId);
//        operateRecordDo.setOperateTime(new Date());
//        operateRecordDo.setContent("修改了入库单信息");
//        operateRecordDo.setRemarks(JSON.toJSONString(res));
//
//        operateRecordDao.insert(operateRecordDo);
//    }

    //编辑校验
    private void updateCheck(Object req) {

    }

    //做修改之前要执行的业务定制处理
    private void handlerUpdateBefore(OrderInputDo entityDo, Long userId) {
        entityDo.setUpdateBy(userId);
        entityDo.setUpdateTime(new Date());
    }


    @Override
    public int delete(Long id, Long userId) {
        OrderInputDo entityDo = dao.selectById(id);
        handlerDeleteBefore(entityDo, userId);
        dao.updateById(entityDo);
        dao.deleteById(id);
        //删除从表
        LambdaQueryWrapper<OrderInputPackageDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderInputPackageDo::getOrderInputId, id);
        orderInputPackageDao.delete(wrapper);

        LambdaQueryWrapper<OrderInputProductDo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(OrderInputProductDo::getOrderInputId, id);
        orderInputProductDao.delete(productWrapper);
        return 1;
    }

    //做删除之前要执行的业务定制处理
    private void handlerDeleteBefore(OrderInputDo entityDo, Long userId) {
        entityDo.setDeleteBy(userId);
        entityDo.setDeleteTime(new Date());
    }

    @Override
    public OderInputDetailRes detail(Long id) {
        OrderInputDo entityDo = dao.selectById(id);
        OderInputDetailRes res = new OderInputDetailRes();
        ShopDo shopDo = shopDao.selectById(entityDo.getShopId());
        if (shopDo != null) {
            res.setShopName(shopDo.getShopName());
        }

        res.setExpireTime(entityDo.getExpireTime());
        res.setShopId(entityDo.getShopId());
        res.setStorageId(entityDo.getStorageId());
        StorageDo storageDo = storageDao.selectById(entityDo.getStorageId());
        if (storageDo != null) {
            res.setStorage(storageDo.getStorageName());
        }
        FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(entityDo.getFbaStorageId());
        if (fbaStorageDo != null) {
            res.setFbaStorage(fbaStorageDo.getFbaCode());
        }
        res.setId(entityDo.getId());
        res.setOrderInputNumber(entityDo.getOrderInputNumber());
        res.setDeliveryDate(entityDo.getDeliveryDate());
        res.setCarriageTrackNo(entityDo.getCarriageTrackNo());
        res.setCarriageType(entityDo.getCarriageType());
        res.setCountryName(entityDo.getCountryName());

//        DicBusinessItemDo carriageTypeItemDo = dicBusinessItemDao.selectById(entityDo.getCarriageType());
        String carriageTypeItemDo = getInitValueMap().get("carriageType").get(entityDo.getCarriageType().intValue());
        if (carriageTypeItemDo != null) {
            res.setCarriageTypeName(carriageTypeItemDo);
        }
        res.setSendType(entityDo.getSendType());
//        DicBusinessItemDo sendtypeItemDo = dicBusinessItemDao.selectById(entityDo.getSendType());
        String sendtypeItemDo = getInitValueMap().get("sendType").get(entityDo.getSendType().intValue());
        if (sendtypeItemDo != null) {
            res.setSendTypeName(sendtypeItemDo);
        }
        res.setCarriageTrackNo(entityDo.getCarriageTrackNo());
        res.setFbaTurn(entityDo.getFbaTurn());
        String fbaTurn = getInitValueMap().get("fbaTurn").get(entityDo.getFbaTurn());
        if (fbaTurn != null) {
            res.setFbaTurnName(fbaTurn);
        }
        DicBusinessItemDo businessItemDo = dicBusinessItemDao.selectById(entityDo.getStatus());
        if (businessItemDo != null) {
            res.setStatus(businessItemDo.getDicItemValue());
        }
        res.setFbaNo(entityDo.getFbaNo());
        res.setFbaPo(entityDo.getFbaPo());
        res.setFbaFileUrl(fileService.getFilePath(entityDo.getFbaFileId()));
        res.setClearFileUrl(fileService.getFilePath(entityDo.getClearFileId()));
        res.setFbaFileId(entityDo.getFbaFileId());
        res.setClearFileId(entityDo.getClearFileId());
        FileDo fileDo = fileService.getBaseMapper().selectById(entityDo.getFbaFileId());
        if (fileDo != null) {
            res.setFileName(fileDo.getFileName());
        }
        res.setVolume(entityDo.getVolume());
        res.setTips(entityDo.getTips());
        res.setSeaFee(entityDo.getSeaFee());
        res.setClearanceFee(entityDo.getClearanceFee());
        res.setServiceFee(entityDo.getServiceFee());
        res.setTaxFee(entityDo.getTaxFee());
        List<OrderInputPackageDetail> packageList = new ArrayList<>();
        LambdaQueryWrapper<OrderInputPackageDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderInputPackageDo::getOrderInputId, entityDo.getId());
        List<OrderInputPackageDo> orderInputPackageDos = orderInputPackageDao.selectList(wrapper);

        List<OrderInputProductDo> inputProductDoList = new ArrayList<>();
        Map<Long, List<OrderInputProductDo>> packProductMap = new HashMap<>();
        Map<Long, ProductInfoDo> productInfoMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(orderInputPackageDos)) {
            LambdaQueryWrapper<OrderInputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            productDoLambdaQueryWrapper.eq(OrderInputProductDo::getOrderInputId, entityDo.getId())
                    .in(OrderInputProductDo::getPackageId, orderInputPackageDos.stream().map(OrderInputPackageDo::getId).collect(Collectors.toList()));
            inputProductDoList = orderInputProductDao.selectList(productDoLambdaQueryWrapper);
            packProductMap = inputProductDoList.stream().collect(Collectors.groupingBy(OrderInputProductDo::getPackageId));

            if (!CollectionUtils.isEmpty(inputProductDoList)) {
                productInfoMap = productInfoDao.selectList(new LambdaQueryWrapper<ProductInfoDo>()
                        .in(ProductInfoDo::getId, inputProductDoList.stream().map(OrderInputProductDo::getProductId).collect(Collectors.toList())))
                        .stream().collect(Collectors.toMap(ProductInfoDo::getId, i -> i, (v1, v2) -> v1));
            }
            for (OrderInputPackageDo packageDo : orderInputPackageDos) {
                OrderInputPackageDetail packageDetail = new OrderInputPackageDetail();
                packageDetail.setId(packageDo.getId());
                packageDetail.setCount(packageDo.getPackageCount());
                packageDetail.setHeight(packageDo.getPackageHeight());
                packageDetail.setLength(packageDo.getPackageLenght());
                packageDetail.setWeight(packageDo.getPackageWeight());
                packageDetail.setWidth(packageDo.getPackageWidth());
                packageDetail.setBoxTypeNumber(packageDo.getBoxTypeNumber());
                List<OrderInputProductDetail> productAddList = new ArrayList<>();

                List<OrderInputProductDo> orderInputProductDos = packProductMap.get(packageDo.getId());
                if (!CollectionUtils.isEmpty(orderInputProductDos)) {
                    for (OrderInputProductDo productDo : orderInputProductDos) {
                        OrderInputProductDetail productDetail = new OrderInputProductDetail();
                        ProductInfoDo productInfoDo = productInfoMap.get(productDo.getProductId());
                        if (productInfoDo != null) {
                            BeanUtils.copyProperties(productInfoDo, productDetail);
                            productDetail.setProductId(productInfoDo.getId());
                            productDetail.setCount(productDo.getCount());
//                            productDetail.setCommoditySku(productInfoDo.getCommoditySku());
//                            productDetail.setProductName(productInfoDo.getProductName());
//                            productDetail.setStorageSku(productInfoDo.getStorageSku());
//                            productDetail.setCommodityName(productInfoDo.getCommodityName());
                            productAddList.add(productDetail);
                        }
                    }
                }
                packageDetail.setProductList(productAddList);
                packageList.add(packageDetail);
            }
        }
        //查询日志
        List<OperateRes> operateResList = operateRecordDao.getOperateList(entityDo.getId(), 2);
        res.setOperateResList(operateResList);
        res.setPackageList(packageList);
        //获取包裹汇总信息
//        res.setProductList(this.getProductList(id));
        List<InputMarkProduct> productList = new ArrayList<>();
        for (OrderInputPackageDo orderInputPackageDo : orderInputPackageDos) {
            List<OrderInputProductDo> packProductList = packProductMap.get(orderInputPackageDo.getId());
            if (packProductList == null) {
                continue;
            }
            for (OrderInputProductDo inputProductDo : packProductList) {
                InputMarkProduct markProduct = new InputMarkProduct();
                markProduct.setProductId(inputProductDo.getProductId());
                ProductInfoDo productInfoDo = productInfoMap.get(inputProductDo.getProductId());
                if (productInfoDo != null) {
                    markProduct.setProductName(productInfoDo.getProductName());
                    markProduct.setCommoditySku(productInfoDo.getCommoditySku());
                    markProduct.setStorageSku(productInfoDo.getStorageSku());
                    markProduct.setLength(productInfoDo.getLength());
                    markProduct.setHeight(productInfoDo.getHeight());
                    markProduct.setWidth(productInfoDo.getWidth());
                    markProduct.setWeight(productInfoDo.getWeight());
                }
                markProduct.setBrokenCount(inputProductDo.getBrokenCount());
                markProduct.setReceiveCount(inputProductDo.getReceiveCount());
                markProduct.setCount(inputProductDo.getCount() * orderInputPackageDo.getPackageCount());
                productList.add(markProduct);
            }
        }
        res.setProductList(this.handlerDistinctSku(productList));
        //费用明细
        res.setProjectResList(this.getHeaderContainerProjectRes(entityDo.getId()));


        //有效期
        List<OrderInputExpireDo> expireDoList = orderInputExpireDao.selectList(new LambdaQueryWrapper<OrderInputExpireDo>()
                .eq(OrderInputExpireDo::getOrderId, id));
        List<OrderInputProductExpireRes> resList = new ArrayList<>();
        for (OrderInputExpireDo expireDo : expireDoList) {
            OrderInputProductExpireRes expireRes = new OrderInputProductExpireRes();
            BeanUtils.copyProperties(expireDo, expireRes);
            resList.add(expireRes);
        }
        res.setProductExpireList(resList);
        return res;
    }


    //新版费用详情
    public List<HeaderContainerProjectRes> getHeaderContainerProjectRes(Long id) {
        HeaderContainerOrderDo containerOrderDo = headerContainerOrderDao.selectOne(new LambdaQueryWrapper<HeaderContainerOrderDo>()
                .eq(HeaderContainerOrderDo::getFirstVesselOrderId, id));
        if (containerOrderDo == null) {
            return null;
        }

        ManageBillDo billDo = null;
        if (containerOrderDo.getBillId() != null) {
            billDo = manageBillDao.selectById(containerOrderDo.getBillId());
        } else {
            //根据orderId 获取 柜号 再获取账单
            HeaderContainerDo headerContainerDo = headerContainerDao.getHeaderByOrderId(id);
            if (headerContainerDo == null) {
                return null;
            }
            billDo = manageBillDao.getBillByHeaderId(headerContainerDo.getId());
        }
        if (billDo == null) {
            return null;
        }
        List<ManageHeaderPriceItemDo> itemDoList = manageHeaderPriceItemDao.selectList(new LambdaQueryWrapper<ManageHeaderPriceItemDo>()
                .eq(ManageHeaderPriceItemDo::getBillId, billDo.getId())
                .eq(ManageHeaderPriceItemDo::getType, "beginBill"));
        List<HeaderContainerProjectRes> resList = new ArrayList<>();
        for (ManageHeaderPriceItemDo item : itemDoList) {
            HeaderContainerProjectRes res = new HeaderContainerProjectRes();
            if (item.getProjectId() != null) {
                StorageServiceProjectDo projectDo = storageServiceDao.selectById(item.getProjectId());
                if (projectDo == null) {
                    continue;
                }
                res.setProjectName(projectDo.getProjectName());
            } else {
                res.setProjectName(item.getValue());
            }
            res.setCurrencyType(item.getCurrencyType() + "");
            res.setCurrencyTypeName(item.getCurrencyType() == 107L ? "RMB" : (item.getCurrencyType() == 108L ? "JPY" : "USD"));
            res.setPrice(item.getPrice() + item.getTax());
            resList.add(res);
        }
        return resList;
    }

    /**
     * 获取包裹汇总信息
     *
     * @param id
     * @return
     */
    @Override
    public List<InputMarkProduct> getProductList(Long id) {
        List<InputMarkProduct> productList = new ArrayList<>();

        LambdaQueryWrapper<OrderInputPackageDo> packageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        packageDoLambdaQueryWrapper.eq(OrderInputPackageDo::getOrderInputId, id);
        List<OrderInputPackageDo> orderInputPackageDos = orderInputPackageDao.selectList(packageDoLambdaQueryWrapper);
        if (!CollectionUtils.isEmpty(orderInputPackageDos)) {

            LambdaQueryWrapper<OrderInputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            productDoLambdaQueryWrapper.eq(OrderInputProductDo::getOrderInputId, id)
                    .in(OrderInputProductDo::getPackageId, orderInputPackageDos.stream().map(OrderInputPackageDo::getId).collect(Collectors.toList()));
            List<OrderInputProductDo>  inputProductDoList = orderInputProductDao.selectList(productDoLambdaQueryWrapper);
            Map<Long, List<OrderInputProductDo>> packProductMap = inputProductDoList.stream().collect(Collectors.groupingBy(OrderInputProductDo::getPackageId));

            Map<Long, ProductInfoDo> productInfoMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(inputProductDoList)) {
                productInfoMap = productInfoDao.selectList(new LambdaQueryWrapper<ProductInfoDo>()
                                .in(ProductInfoDo::getId, inputProductDoList.stream().map(OrderInputProductDo::getProductId).collect(Collectors.toList())))
                        .stream().collect(Collectors.toMap(ProductInfoDo::getId, i -> i, (v1, v2) -> v1));
            }
            for (OrderInputPackageDo orderInputPackageDo : orderInputPackageDos) {
                List<OrderInputProductDo> productDoList = packProductMap.get(orderInputPackageDo.getId());
                if (!CollUtil.isEmpty(productDoList)) {
                    for (OrderInputProductDo inputProductDo : productDoList) {
                        InputMarkProduct markProduct = new InputMarkProduct();
                        markProduct.setProductId(inputProductDo.getProductId());
                        ProductInfoDo productInfoDo = productInfoMap.get(inputProductDo.getProductId());
                        if (productInfoDo != null) {
                            markProduct.setProductName(productInfoDo.getProductName());
                            markProduct.setCommoditySku(productInfoDo.getCommoditySku());
                            markProduct.setStorageSku(productInfoDo.getStorageSku());
                            markProduct.setLength(productInfoDo.getLength());
                            markProduct.setHeight(productInfoDo.getHeight());
                            markProduct.setWidth(productInfoDo.getWidth());
                            markProduct.setWeight(productInfoDo.getWeight());
                        }
                        markProduct.setBrokenCount(inputProductDo.getBrokenCount());
                        markProduct.setReceiveCount(inputProductDo.getReceiveCount());
                        markProduct.setCount(inputProductDo.getCount() * orderInputPackageDo.getPackageCount());
                        productList.add(markProduct);
                    }
                }
            }
        }
        return handlerDistinctSku(productList);
    }


    private List<InputMarkProduct> handlerDistinctSku(List<InputMarkProduct> productList) {
        List<InputMarkProduct> productsNew = new ArrayList<>();
        Map<Long, List<InputMarkProduct>> collect = productList.stream().collect(Collectors.groupingBy(InputMarkProduct::getProductId));
        if (!CollectionUtils.isEmpty(collect)) {
            for (Long key : collect.keySet()) {
                List<InputMarkProduct> products = collect.get(key);
                if (products.size() == 0) {
                    continue;
                }
                InputMarkProduct inputMarkProduct = products.get(0);

                if (products.size() > 1) {
                    int sum = products.stream().mapToInt(InputMarkProduct::getCount).sum();
                    int rec = products.stream().mapToInt(InputMarkProduct::getReceiveCount).sum();
                    int bro = products.stream().mapToInt(InputMarkProduct::getBrokenCount).sum();

                    inputMarkProduct.setCount(sum);
                    inputMarkProduct.setReceiveCount(rec);
                    inputMarkProduct.setBrokenCount(bro);
                    productsNew.add(inputMarkProduct);
                } else {
                    productsNew.addAll(products);
                }
            }
        }
        return productsNew;
    }


    private Map<String, Map<Integer, String>> getInitValueMap() {

        Map<String, Map<Integer, String>> result = new HashMap<>();

        Map<Integer, String> carriageType = new HashMap();
        carriageType.put(0, "散货");
        carriageType.put(1, "整柜");
        carriageType.put(2, "空运");

        Map<Integer, String> sendType = new HashMap();
        sendType.put(0, "自发头程");
        sendType.put(1, "筋斗云头程");
        sendType.put(2, "退货入库");

        Map<Integer, String> fbaTurn = new HashMap();
        fbaTurn.put(0, "否");
        fbaTurn.put(1, "是");

        Map<Integer, String> status = new HashMap();
        status.put(-1, "驳回");
        status.put(0, "已下单");
        status.put(1, "已审核");
        status.put(2, "待入库");
        status.put(3, "已入库");
        status.put(4, "已上架");

        result.put("carriageType", carriageType);
        result.put("sendType", sendType);
        result.put("fbaTurn", fbaTurn);
        result.put("status", status);

        return result;
    }

    @Override
    public SingleResult pageInit(Long userId, Long companyId) {
        Map result = new HashMap();
        result.put("shopList", shopService.selectShopListInit(userId, companyId));
        result.put("statusList", dicBusinessItemService.getDicItemList(DicBusinessConstant.inPutStatus));
        result.put("storage", storageService.storageList());
        //运输方式
        List<LanguageValueEntity> carriageType = new ArrayList<>();
        carriageType.add(new LanguageValueEntity(0, "散货"));
        carriageType.add(new LanguageValueEntity(1, "整柜"));
        carriageType.add(new LanguageValueEntity(2, "空运"));

        result.put("transportTypeList", carriageType);

        //发货方式
        List<LanguageValueEntity> sendType = new ArrayList<>();
        sendType.add(new LanguageValueEntity(0, "自发头程"));
        sendType.add(new LanguageValueEntity(1, "筋斗云头程"));
        result.put("sendOutTypeList", sendType);
        return SingleResult.success(result);
    }

    @Override
    public PageResult getListPage(Map<String, String> map) {
        QueryWrapper<OrderInputDo> wrapper = queryBuild(map);
        IPage<OrderInputDo> page = pageInit(map);
        page = this.page(page, wrapper);
        List<OrderInputPageRes> resList = handlerListAfter(page.getRecords());
        PageResult result = new PageResult(resList, (int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), (int) page.getPages());
        result.setMapInfo(census(map));
        return result;
    }

    @Override
    public List<ExcelImportPackageRes> importExcel(MultipartFile file, Long companyId) throws IOException {
        if (file == null) throw new BizExceptionI18("no.file");
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        if (!GlobalConstants.IMG_TYPE_XLS.equals(suffix.toUpperCase()) &&
                !GlobalConstants.IMG_TYPE_XLSX.equals(suffix.toUpperCase())) {
            throw new BizExceptionI18("file.form.incorrect");
        }
        List<ExcelImportVo> excelImportVoList = ExcelUtils.importExcel(file, 0, 1, ExcelImportVo.class);
        if (excelImportVoList.size() < 1) throw new BizExceptionI18("no.content");
        List<ExcelImportPackageRes> packageList = new ArrayList<>();
        Map<String, List<ExcelImportVo>> map = new LinkedHashMap<>();
        map= excelImportVoList.stream().filter(product -> product != null)
                .filter(product -> StringUtils.isNotBlank(product.getCommoditySku()))
                .collect(Collectors.groupingBy(ExcelImportVo::getPackageNo, LinkedHashMap::new, Collectors.toList()));
        if (!CollectionUtils.isEmpty(map)) {
            for (String packageNo : map.keySet()) {
                List<ExcelImportVo> excelImportVos = map.get(packageNo);
                if (!CollectionUtils.isEmpty(excelImportVos)) {
                    ExcelImportPackageRes packageAdd = new ExcelImportPackageRes();
                    verfyPackageInfo(excelImportVos, packageAdd);
                    packageAdd.setPackageCount(excelImportVos.get(0).getPackageCount());
                    packageAdd.setPackageHeight(excelImportVos.get(0).getHeight().floatValue());
                    packageAdd.setPackageLenght(excelImportVos.get(0).getLength().floatValue());
                    packageAdd.setPackageWidth(excelImportVos.get(0).getWidth().floatValue());
                    packageAdd.setPackageWeight(excelImportVos.get(0).getWeight().floatValue());

                    List<JSONObject> productAddList = new ArrayList<>();
                    for (ExcelImportVo excelImportVo : excelImportVos) {
                        //商品
                        JSONObject productAdd = new JSONObject();
                        LambdaQueryWrapper<ProductInfoDo> wrapper = new LambdaQueryWrapper<>();
                        wrapper.or(productWrapper -> {
                            productWrapper.eq(ProductInfoDo::getCommoditySku, excelImportVo.getCommoditySku()).or()
                                    .eq(ProductInfoDo::getStorageSku, excelImportVo.getCommoditySku());
                        });
                        wrapper.eq(ProductInfoDo::getCompanyId, companyId);
                        ProductInfoDo productInfoDo = productInfoDao.selectOne(wrapper);
                        if (productInfoDo != null) {
                            productAdd.put("productId", productInfoDo.getId());
                            productAdd.put("commoditySku", productInfoDo.getCommoditySku());
                            productAdd.put("storageSku", productInfoDo.getStorageSku());
                            productAdd.put("productName", productInfoDo.getCommodityName());
                            productAdd.put("createTime", productInfoDo.getCreateTime());
                        } else {
                            productAdd.put("productId", "");
                            productAdd.put("commoditySku", "产品不存在，请检查SKU" + excelImportVo.getCommoditySku());
                            productAdd.put("productName", "");
                            productAdd.put("storageSku", "");
                            productAdd.put("createTime", "");
                        }
                        productAdd.put("count", excelImportVo.getCount());

                        productAddList.add(productAdd);
                    }

                    packageAdd.setProductDetailList(productAddList);

                    packageAdd.setBoxTypeNumber(packageNo);

                    packageList.add(packageAdd);
                }
            }
        }

        return packageList;
    }

    private void verfyPackageInfo(List<ExcelImportVo> excelImportVos, ExcelImportPackageRes addReq) {
        ExcelImportVo excelData = excelImportVos.get(0);
        try {
            if (excelData.getLength() == null || excelData.getLength() == 0) {
                throw new BizExceptionI18(SysConstant.INPUT_LENGTH_ERROR, excelData.getCommoditySku());
            }
            if (excelData.getHeight() == null || excelData.getHeight() == 0) {
                throw new BizExceptionI18(SysConstant.INPUT_HEIGHT_ERROR, excelData.getCommoditySku());
            }
            if (excelData.getWidth() == null || excelData.getWidth() == 0) {
                throw new BizExceptionI18(SysConstant.INPUT_WIDTH_ERROR, excelData.getCommoditySku());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizExceptionI18(SysConstant.INPUT_SIZE_ERROR, excelData.getCommoditySku());
        }
    }

    //统计信息
    private Map census(Map<String, String> wrapper) {
        List<Map> result = new ArrayList<>();
        Map mapTotal = new HashMap();
        wrapper.put("status", "");
        List<OrderInputDo> total = dao.selectList(queryBuild(wrapper));
        mapTotal.put("count", total.size());
        mapTotal.put("name", StringsUtil.createI18Message("全部"));
        mapTotal.put("id", null);
        result.add(mapTotal);
        Map<Long, List<OrderInputDo>> collect = total.stream().collect(Collectors.groupingBy(OrderInputDo::getStatus));

        List<DicItemRes> businessItemDoList = dicBusinessItemService.getDicItemList(DicBusinessConstant.inPutStatus);
        if (!CollectionUtils.isEmpty(businessItemDoList)) {
            for (DicItemRes itemDo : businessItemDoList) {
                wrapper.put("status", itemDo.getId() + "");
                Map map = new HashMap();
                List<OrderInputDo> list = collect.get(itemDo.getId());
                if (list == null) {
                    map.put("count", 0);
                } else {
                    map.put("count", list.size());
                }
                map.put("name", itemDo.getValue());
                map.put("id", itemDo.getId());
                result.add(map);
            }
        }
        Map map = new HashMap();
        map.put("census", result);
        return map;
    }

    //查询分页列表之后对列表数据的处理
    private List<OrderInputPageRes> handlerListAfter(List<OrderInputDo> list) {
        List<OrderInputPageRes> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            for (OrderInputDo orderInputDo : list) {
                OrderInputPageRes res = new OrderInputPageRes();
                res.setId(orderInputDo.getId());
                res.setCarriageTrackNo(orderInputDo.getCarriageTrackNo());
                res.setCreateTime(orderInputDo.getCreateTime());
                res.setInputDate(orderInputDo.getInputTime());
                res.setDeliveryDate(orderInputDo.getDeliveryDate());
                ShopDo shopDo = shopDao.selectById(orderInputDo.getShopId());
                if (shopDo != null) {
                    res.setShopName(shopDo.getShopName());
                }
                res.setOrderInputNumber(orderInputDo.getOrderInputNumber());
                StorageDo storageDo = storageDao.selectById(orderInputDo.getStorageId());
                if (storageDo != null) {
                    res.setStorage(storageDo.getStorageName());
                }
                res.setTips(orderInputDo.getTips());
                res.setVolume(orderInputDo.getVolume());
                res.setStatusInt(orderInputDo.getStatus());
                DicBusinessItemDo businessItemDo = dicBusinessItemDao.selectById(orderInputDo.getStatus());
                if (businessItemDo != null) {
                    res.setStatus(businessItemDo.getDicItemValue());
                }
                String carriageTypeItemDo = getInitValueMap().get("carriageType").get(orderInputDo.getCarriageType().intValue());
                if (carriageTypeItemDo != null) {
                    res.setCarriageType(carriageTypeItemDo);
                }
//        DicBusinessItemDo sendtypeItemDo = dicBusinessItemDao.selectById(entityDo.getSendType());
                String sendtypeItemDo = getInitValueMap().get("sendType").get(orderInputDo.getSendType().intValue());
                if (sendtypeItemDo != null) {
                    res.setSendType(sendtypeItemDo);
                }
                LambdaQueryWrapper<OrderInputPackageDo> packageWrapper = new LambdaQueryWrapper<>();
                packageWrapper.eq(OrderInputPackageDo::getOrderInputId, orderInputDo.getId());
                List<OrderInputPackageDo> packageDoList = orderInputPackageDao.selectList(packageWrapper);
                if (packageDoList == null || packageDoList.size() < 1) continue;
                int pacakgeCount = 0, totalCount = 0;
                for (OrderInputPackageDo packageDo : packageDoList) {
                    pacakgeCount = pacakgeCount + packageDo.getPackageCount();
                    LambdaQueryWrapper<OrderInputProductDo> productWrapper = new LambdaQueryWrapper<>();
                    productWrapper.eq(OrderInputProductDo::getPackageId, packageDo.getId());
                    List<OrderInputProductDo> productDoList = orderInputProductDao.selectList(productWrapper);
                    if (productDoList == null || productDoList.size() < 1) continue;
                    for (OrderInputProductDo productDo : productDoList) {
                        totalCount = totalCount + packageDo.getPackageCount() * productDo.getCount();
                    }
                }
                res.setPackageCount(pacakgeCount);
                res.setTotalCount(totalCount);
                result.add(res);
            }
        }
        return result;
    }

    private IPage<OrderInputDo> pageInit(Map<String, String> map) {
        IPage<OrderInputDo> page = new Page();
        page.setSize(StringUtils.isNotBlank(map.get("pageSize")) ? Long.parseLong(map.get("pageSize")) : 10);
        page.setCurrent(StringUtils.isNotBlank(map.get("current")) ? Long.parseLong(map.get("current")) : 1);
        return page;
    }

    private QueryWrapper<OrderInputDo> queryBuild(Map<String, String> map) {
        QueryWrapper<OrderInputDo> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(map.get("keyword"))) {
            wrapper.and(i -> i.like("order_input_number", map.get("keyword"))
                    .or().like("carriage_track_no", map.get("keyword"))
                    .or().like("tips", map.get("keyword")));
        }
        if (StringUtils.isNotBlank(map.get("shopId"))) {
            wrapper.eq("shop_id", map.get("shopId"));
        }
        if (StringUtils.isNotBlank(map.get("storageId"))) {
            wrapper.eq("storage_id", map.get("storageId"));
        }
        if (StringUtils.isNotBlank(map.get("status"))) {
            wrapper.eq("status", map.get("status"));
        }
        wrapper.eq("company_id", map.get("companyId")).orderByDesc("id");
        return wrapper;
    }

    @Override
    public String exportPackagePdf(Long id, int type, boolean showCountry, HttpServletResponse response) {
        OrderInputDo inputDo = dao.selectById(id);
        QueryWrapper wrapper = new QueryWrapper();
        if (inputDo == null) throw new BizExceptionI18(SysConstant.NO_ORDER_INFO);
        wrapper.eq("order_input_id", id);
        String name = inputDo.getOrderInputNumber() + "_" + TimeUtils.getCurrentDateFormat("HHmmss");
        List<OrderInputPackageDo> packageDoList = orderInputPackageDao.selectList(wrapper);
        List<OrderInputPackagePdfExportDetail> packagePdfExportDetails = new ArrayList<>();
        for (OrderInputPackageDo packageDo : packageDoList) {
            OrderInputPackagePdfExportDetail detail = new OrderInputPackagePdfExportDetail();
            detail.setPackageWeight(packageDo.getPackageWeight());
            detail.setSize((int) packageDo.getPackageLenght() + "*" + (int) packageDo.getPackageWidth() + "*" + (int) packageDo.getPackageHeight());
            detail.setCount(packageDo.getPackageCount());
            wrapper = new QueryWrapper();
            wrapper.eq("package_id", packageDo.getId());
            List<OrderInputProductDo> productDoList = orderInputProductDao.selectList(wrapper);
            if (productDoList.size() < 1) {
                detail.setProductType("含まない");
            } else if (productDoList.size() == 1) {
                detail.setProductType("単一のSKU");
                ProductInfoDo productInfoDo = productInfoDao.selectById(productDoList.get(0).getProductId());
                if (productInfoDo == null) {
                    detail.setCommoditySku("未知");
                    detail.setStorageSku("未知");
                } else {
                    detail.setCommoditySku(productInfoDo.getCommoditySku());
                    detail.setStorageSku(productInfoDo.getStorageSku());
                }
                detail.setSkuCount(productDoList.get(0).getCount());
            } else {
                detail.setProductType("混在のSKU");
            }
            packagePdfExportDetails.add(detail);
        }
        PdfUtils pdfUtils = new PdfUtils(name, response);

        String address = "〒";
        if (type == 0) { // 10 * 10
            pdfUtils.printPackageCodePDF(inputDo, packagePdfExportDetails, showCountry);
        } else {// 10 * 6
            pdfUtils.printPackageCodePDF221(inputDo, packagePdfExportDetails, showCountry);
        }
        return filePath + "/" + name;
    }

    @Override
    public String exportProductCodePdf(Long id, HttpServletResponse response) {
        OrderInputDo inputDo = dao.selectById(id);
        if (inputDo == null) throw new BizExceptionI18(SysConstant.NO_ORDER_INFO);
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("order_input_id", id);
        OderInputDetailRes detailRes = detail(id);
        String name = inputDo.getOrderInputNumber() + "_" + TimeUtils.getCurrentDateFormat("HHmmss");
        final int[] count = new int[1];
        if (detailRes.getPackageList() != null && detailRes.getPackageList().size() > 0) {
            detailRes.getPackageList().stream().forEach(packageBean -> {
                if (packageBean.getProductList() != null && packageBean.getProductList().size() > 0) {
                    packageBean.getProductList().stream().forEach(product -> {
                        count[0] = count[0] + packageBean.getCount() * product.getCount();
                    });
                }
            });
        }
        PdfUtils pdfUtils;
        if (count[0] < 50000) {
//            pdfUtils = new PdfUtils(filePath + "/" + name);
            pdfUtils = new PdfUtils(name, response);
            pdfUtils.printProductCodePdf(detailRes);
            return "下载成功";
        } else {
            return "数据量太大，请联系客服操作";
        }
    }

    @Override
    public SingleResult fbaReturnInit(Long id, Long userId, Long companyId) {
        Map result = fbaRetrunAddInit(userId, companyId);
        if (id != null) {
            FbaReturnInitRes res = new FbaReturnInitRes();
            OrderInputDo orderInputDo = dao.selectById(id);
            if (orderInputDo.getStatus() <= DicBusinessItemConstant.inPutStorage)
                throw new BizExceptionI18(SysConstant.NO_EDIT_ORDER_NO_INPUT);
            res.setShopId(orderInputDo.getShopId());
            res.setStorageId(orderInputDo.getStorageId());
            ShopDo shopDo = shopDao.selectById(orderInputDo.getShopId());
            if (shopDo != null) {
                res.setShopName(shopDo.getShopName());
            }
            StorageDo storageDo = storageDao.selectById(orderInputDo.getStorageId());
            if (storageDo != null) {
                res.setStorage(storageDo.getStorageName());
            }
            res.setOrderInputNumber(orderInputDo.getOrderInputNumber());
            res.setFbaStorageId(orderInputDo.getFbaStorageId());
            res.setFbaFileId(orderInputDo.getFbaFileId());
            res.setFbaFileUrl(fileService.getFilePath(orderInputDo.getFbaFileId()));
            res.setFbaNo(orderInputDo.getFbaNo());
            FbaStorageDo fbaStorageDo = fbaStorageDao.selectById(orderInputDo.getFbaStorageId());
            if (fbaStorageDo != null) {
                res.setFbaStorage(fbaStorageDo.getFbaCode());
            }
            List<FbaOrderOutputPackageUpdateReq> packageList = new ArrayList<>();
            //获取库存
            Map<String, String> param = new HashMap<>();
            param.put("storageId", orderInputDo.getStorageId() + "");
            param.put("shopId", orderInputDo.getShopId() + "");
            List<StockRecordPageRes> stockList = stockRecordService.getList(param);
            Map<Long, List<StockRecordPageRes>> stockListMap = stockList.stream().collect(Collectors.groupingBy(StockRecordPageRes::getProductInfoId));

            LambdaQueryWrapper<OrderInputPackageDo> packageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            packageDoLambdaQueryWrapper.eq(OrderInputPackageDo::getOrderInputId, orderInputDo.getId());
            List<OrderInputPackageDo> orderInputPackageDos = orderInputPackageDao.selectList(packageDoLambdaQueryWrapper);
            if (!CollectionUtils.isEmpty(orderInputPackageDos)) {
                int packageCount = 1;
                for (int i = 0; i < orderInputPackageDos.size(); i++) {
                    OrderInputPackageDo orderInputPackageDo = orderInputPackageDos.get(i);
                    FbaOrderOutputPackageUpdateReq packageDetail = new FbaOrderOutputPackageUpdateReq();
                    packageDetail.setWidth(orderInputPackageDo.getPackageWidth());
                    packageDetail.setWeight(orderInputPackageDo.getPackageWeight());
                    packageDetail.setLength(orderInputPackageDo.getPackageLenght());
                    packageDetail.setCount(orderInputPackageDo.getPackageCount());
                    packageDetail.setHeight(orderInputPackageDo.getPackageHeight());
                    packageDetail.setPoNumber(orderInputDo.getFbaPo());
                    packageDetail.setTips(orderInputDo.getOrderInputNumber() + "-" + (i + 1));
                    packageDetail.setId(orderInputPackageDo.getId());
                    packageCount = packageCount + 1;
                    List<FbaOrderOutputProductDetail> productDetailList = new ArrayList<>();
                    LambdaQueryWrapper<OrderInputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    productDoLambdaQueryWrapper.eq(OrderInputProductDo::getPackageId, orderInputPackageDo.getId());
                    List<OrderInputProductDo> productDoList = orderInputProductDao.selectList(productDoLambdaQueryWrapper);
                    if (!CollectionUtils.isEmpty(productDoList)) {
                        productDoList.forEach(orderInputProductDo -> {
                            FbaOrderOutputProductDetail productDetail = new FbaOrderOutputProductDetail();
                            productDetail.setStorageSku(orderInputProductDo.getCommoditySku());
                            productDetail.setCount(orderInputProductDo.getCount());
                            productDetail.setProductId(orderInputProductDo.getProductId());
                            ProductInfoDo productInfoDo = productInfoDao.selectById(orderInputProductDo.getProductId());
                            if (productInfoDo != null) {
                                productDetail.setStorageSku(productInfoDo.getStorageSku());
                                productDetail.setCommoditySku(productInfoDo.getCommoditySku());
                                productDetail.setCommodityName(productInfoDo.getCommodityName());
                                if (stockListMap.get(productInfoDo.getId()) != null) {
                                    productDetail.setCanSellCount(stockListMap.get(productInfoDo.getId()).get(0).getCanSellCount() -
                                            stockListMap.get(productInfoDo.getId()).get(0).getNoDelivered());
                                } else {
                                    productDetail.setCanSellCount(0);
                                }
                            }
                            productDetailList.add(productDetail);
                        });
                    }
                    packageDetail.setProductList(productDetailList);
                    packageList.add(packageDetail);
                }
            }
            res.setPackageList(packageList);
            result.put("detail", res);
            result.put("shop", shopService.selectShopListInit(userId, companyId));

            //入库上架，不收费用
//            if (orderInputDo.getStatus() == DicBusinessItemConstant.inPutStorage) {
//                handlerStockCount(orderInputDo, userId);
//            }
        }
        return SingleResult.success(result);
    }

    private Map<String, Map<String, String>> fbaRetrunAddInit(Long userId, Long companyId) {

        Map map = new HashMap();
        map.put("storage", storageService.getJpList());
        //fbaStorage
        List<FbaStorageDo> fbaStorageDos = fbaStorageDao.selectList(null);
        List<Map> fbaStorageList = new ArrayList<>();
        fbaStorageDos.forEach(fbaStorageDo -> {
            Map fbaMap = new HashMap();
            fbaMap.put("id", fbaStorageDo.getId());
            fbaMap.put("code", fbaStorageDo.getFbaCode());
            fbaMap.put("name", fbaStorageDo.getFbaName());
            fbaMap.put("address", fbaStorageDo.getAddress());
            fbaMap.put("postCode", fbaStorageDo.getPostCode());
            fbaMap.put("tel", fbaStorageDo.getTelPhone());
            fbaStorageList.add(fbaMap);
        });
        map.put("fbaStorageList", fbaStorageList);
        return map;
    }

    @Override
    public void handlerStockCount(OrderInputDo orderInputDo, Long userId) {
        float volume = 0;
        LambdaQueryWrapper<OrderInputPackageDo> packageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        packageDoLambdaQueryWrapper.eq(OrderInputPackageDo::getOrderInputId, orderInputDo.getId());
        List<OrderInputPackageDo> orderInputPackageDos = orderInputPackageDao.selectList(packageDoLambdaQueryWrapper);
        if (!CollectionUtils.isEmpty(orderInputPackageDos)) {
            for (OrderInputPackageDo orderInputPackageDo : orderInputPackageDos) {
                LambdaQueryWrapper<OrderInputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                productDoLambdaQueryWrapper.eq(OrderInputProductDo::getPackageId, orderInputPackageDo.getId());
                List<OrderInputProductDo> orderInputProductDos = orderInputProductDao.selectList(productDoLambdaQueryWrapper);
                if (!CollectionUtils.isEmpty(orderInputProductDos)) {
                    for (OrderInputProductDo orderInputProductDo : orderInputProductDos) {
                        if (orderInputProductDo.getReceiveCount() == 0 && orderInputProductDo.getBrokenCount() == 0) {
                            orderInputProductDo.setReceiveCount(orderInputProductDo.getCount());
                            orderInputProductDo.setBrokenCount(0);
                        }
                        LambdaQueryWrapper<StockRecordDo> stockRecordDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                        stockRecordDoLambdaQueryWrapper.eq(StockRecordDo::getProductInfoId, orderInputProductDo.getProductId())
                                .eq(StockRecordDo::getShopId, orderInputDo.getShopId())
                                .eq(StockRecordDo::getStorageId, orderInputDo.getStorageId());
                        StockRecordDo stockRecordDo = stockRecordDao.selectOne(stockRecordDoLambdaQueryWrapper);
                        if (stockRecordDo != null) {
                            stockRecordDo.setCanSellCount(stockRecordDo.getCanSellCount()
                                    + orderInputProductDo.getReceiveCount());
                            stockRecordDo.setCanotSellCount(stockRecordDo.getCanotSellCount()
                                    + orderInputProductDo.getBrokenCount());
                            stockRecordDo.setUpdateBy(userId);
                            stockRecordDo.setUpdateTime(new Date());
                            stockRecordDao.updateById(stockRecordDo);
                        } else {
                            stockRecordDo = new StockRecordDo();
                            stockRecordDo.setStorageId(orderInputDo.getStorageId());
                            stockRecordDo.setCanotSellCount(orderInputProductDo.getBrokenCount());
                            stockRecordDo.setCanSellCount(orderInputProductDo.getReceiveCount());
                            stockRecordDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                            stockRecordDo.setCompanyId(orderInputDo.getCompanyId());
                            stockRecordDo.setProductInfoId(orderInputProductDo.getProductId());
                            stockRecordDo.setShopId(orderInputDo.getShopId());
                            stockRecordDo.setUpdateBy(userId);
                            stockRecordDo.setUpdateTime(new Date());
                            stockRecordDao.insert(stockRecordDo);
                        }
                        ProductInfoDo productInfoDo = productInfoDao.selectById(orderInputProductDo.getProductId());
                        if (productInfoDo != null) {
                            volume = volume + productInfoDo.getHeight() * productInfoDo.getWidth() * productInfoDo.getLength() *
                                    (orderInputProductDo.getReceiveCount() + orderInputProductDo.getBrokenCount()) / 1000000;
                        }
                        volume = new BigDecimal(volume).setScale(2, RoundingMode.HALF_UP).floatValue();
                        orderInputDo.setVolume(volume);
                        updateById(orderInputDo);
                        stockLogService.saveAutoSendOutLog(orderInputProductDo.getProductId(), orderInputDo.getShopId(), orderInputDo.getStorageId(),
                                orderInputProductDo.getReceiveCount(), stockRecordDo.getCanSellCount(),
                                orderInputDo.getCompanyId(), orderInputDo.getOrderInputNumber(), userId);
                    }
                }
            }
        }

//        //库存库位分配情况
//        Map<Long, List<InputOrderMarkProductReq>> rackMap = new HashMap<>();
//        if (req.getProductInfo() != null) {
//            rackMap = req.getProductInfo().stream().collect(Collectors.groupingBy(InputOrderMarkProductReq::getProductId));
//        }
//        //orderInputProductDos 将入库产品汇总一下 保存到新库存表 先进先出
//        Map<Long, List<OrderInputProductDo>> listMap = productDoList.stream().collect(Collectors.groupingBy(OrderInputProductDo::getProductId));
//        Set<Long> productIdList = listMap.keySet();
//
//        for (Long productId : productIdList) {
//            List<OrderInputProductDo> list = listMap.get(productId);
//            ProductStockDo stockDo = new ProductStockDo();
//            stockDo.setCompanyId(orderInputDo.getCompanyId());
//            stockDo.setCreateBy(userId);
//            stockDo.setCreateTime(new Date());
//            stockDo.setProductId(productId);
//            stockDo.setStorageId(orderInputDo.getStorageId());
//            stockDo.setGoodQuantity(list.stream().mapToInt(OrderInputProductDo::getReceiveCount).sum());
//            stockDo.setReceiveGoodQuantity(stockDo.getGoodQuantity());
//            stockDo.setBadQuantity(list.stream().mapToInt(OrderInputProductDo::getBrokenCount).sum());
//            stockDo.setReceiveQuantity(stockDo.getGoodQuantity() + stockDo.getBadQuantity());
//            stockDo.setOrderId(orderInputDo.getId());
//            stockDo.setOrderType("IB");//入库单
////            stockDo.setShopId(orderInputDo.getShopId());
//            if (stockDo.getReceiveQuantity() == 0) {
//                continue;
//            }
//            //单位成本 * 单位体积
//            productStockDao.insert(stockDo);
//
//            if (rackMap.get(productId) == null || rackMap.get(productId).get(0).getList().size() == 0) {
//                //添加到库位表
//                ProductStockRackDo rackDo = new ProductStockRackDo();
//                rackDo.setGoodQuantity(stockDo.getGoodQuantity());
//                rackDo.setBadQuantity(stockDo.getBadQuantity());
//                rackDo.setStockId(stockDo.getId());
//                rackDo.setCreateTime(new Date());
//                productStockRackDao.insert(rackDo);
//
//                ProductStockFlowingDo flowingDo = new ProductStockFlowingDo();
//                flowingDo.setType("input");
//                flowingDo.setNoteNo(orderInputDo.getOrderInputNumber());
//                flowingDo.setProductId(productId);
//                flowingDo.setStorageId(orderInputDo.getStorageId());
//                flowingDo.setGoodQuantity(rackDo.getGoodQuantity());
//                flowingDo.setBadQuantity(rackDo.getBadQuantity());
//                flowingDo.setCreateTime(new Date());
//                flowingDo.setCreateBy(userId);
//                flowingDo.setCompanyId(orderInputDo.getCompanyId());
//                flowingDo.setShopId(orderInputDo.getShopId());
//                flowingDo.setRackId(null);
//                productStockFlowingDao.insert(flowingDo);
//            } else {
//                List<InputOrderRackReq> rackReqList = rackMap.get(productId).get(0).getList();
//                if (rackReqList.stream().mapToInt(InputOrderRackReq::getAvailNum).sum() != rackMap.get(productId).get(0).getReceiveCount()) {
//                    throw new BizException(SysConstant.OrderInput_GoodQuantity_Error);
//                }
//                if (rackReqList.stream().mapToInt(InputOrderRackReq::getDamageNum).sum() != rackMap.get(productId).get(0).getBrokenCount()) {
//                    throw new BizException(SysConstant.OrderInput_BadQuantity_Error);
//                }
//                for (InputOrderRackReq rackReq : rackReqList) {
//                    ProductStockRackDo rackDo = new ProductStockRackDo();
//                    rackDo.setGoodQuantity(rackReq.getAvailNum());
//                    rackDo.setBadQuantity(rackReq.getDamageNum());
//                    rackDo.setStockId(stockDo.getId());
//                    rackDo.setRackId(rackReq.getLocationId());
//                    rackDo.setCreateTime(new Date());
//                    productStockRackDao.insert(rackDo);
//
//                    //添加库存流水
//                    ProductStockFlowingDo flowingDo = new ProductStockFlowingDo();
//                    flowingDo.setType("input");
//                    flowingDo.setNoteNo(orderInputDo.getOrderInputNumber());
//                    flowingDo.setProductId(productId);
//                    flowingDo.setStorageId(orderInputDo.getStorageId());
//                    flowingDo.setGoodQuantity(rackReq.getAvailNum());
//                    flowingDo.setBadQuantity(rackReq.getDamageNum());
//                    flowingDo.setCreateTime(new Date());
//                    flowingDo.setCreateBy(userId);
//                    flowingDo.setCompanyId(orderInputDo.getCompanyId());
//                    flowingDo.setShopId(orderInputDo.getShopId());
//                    flowingDo.setRackId(rackReq.getLocationId());
//                    productStockFlowingDao.insert(flowingDo);
//                }
//            }
//        }
//
//        float inputFee = 0f;
//        if (volume > 3 && orderInputDo.getCarriageType() != 1) {
//            inputFee = volume * (750 + 810);
//        } else {
//            inputFee = volume * 750;
//        }
//        if (orderInputDo.getSendType() == 0)
////            costService.add(1, orderInputDo.getOrderInputNumber() + "入库费用",
////                    orderInputDo.getSeaFee() + orderInputDo.getSeaFee() + inputFee * 1.1
////                            + orderInputDo.getClearanceFee() + orderInputDo.getTaxFee(),
////                    orderInputDo.getShopId(), orderInputDo.getCompanyId(), orderInputDo.getId());
//        operateRecordDao.operateAddRecord(SysConstant.OPERATE_INPUT_ORDER, orderInputDo.getId(), userId,2);
    }


    @Override
    public void exportExcel(List<Long> ids, Long companyId, HttpServletResponse response) {
        List<OrderInputDo> orderInputDoList = null;
        if (CollectionUtils.isEmpty(ids)) {
//            QueryWrapper<OrderOutputDo> wrapper = queryBuild(map);
//            orderInputDoList = this.baseMapper.selectList(wrapper);
            throw new BizExceptionI18(SysConstant.PLS_CHOOSE_EXPORT_DATA);
        } else {
            LambdaQueryWrapper<OrderInputDo> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(OrderInputDo::getId, ids).orderByDesc(OrderInputDo::getId);
            orderInputDoList = this.baseMapper.selectList(wrapper);
        }

        if (orderInputDoList.size() > 5000) {
//            response.sendError(500, "数据超过5000条，请分日期导出");
            throw new BizExceptionI18(SysConstant.ORDER_COUNT_OVERSIZE_5000);
        }
        List<OrderInputExcelExportInfoVo> excelExportVoList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(orderInputDoList)) {
            for (OrderInputDo orderOutputDo : orderInputDoList) {
                OrderInputExcelExportInfoVo excelExportVo = new OrderInputExcelExportInfoVo();

                BeanUtils.copyProperties(orderOutputDo, excelExportVo);

                DicBusinessItemDo businessItemDo = dicBusinessItemDao.selectById(orderOutputDo.getStatus());
                if (businessItemDo != null) {
                    excelExportVo.setStatus(businessItemDo.getDicItemValue());
                }
                ShopDo shopDo = shopDao.selectById(orderOutputDo.getShopId());
                if (shopDo != null) {
                    excelExportVo.setShopName(shopDo.getShopName());
                }
                StorageDo storageDo = storageDao.selectById(orderOutputDo.getStorageId());
                if (storageDo != null) {
                    excelExportVo.setStorageName(storageDo.getStorageName());
                }
                excelExportVo.setSendType(orderOutputDo.getSendType() + "");
                excelExportVo.setCarriageType(orderOutputDo.getCarriageType() + "");
//
                LambdaQueryWrapper<OrderInputPackageDo> packageWrapper = new LambdaQueryWrapper<>();
                packageWrapper.eq(OrderInputPackageDo::getOrderInputId, orderOutputDo.getId());
                List<OrderInputPackageDo> packageDoList = orderInputPackageDao.selectList(packageWrapper);
                List<OrderInputExcelExportPackageInfoVo> excelExportPackageInfoVoList = new ArrayList<>();
                if (packageDoList == null || packageDoList.size() < 1) continue;
                int pacakgeCount = 0, totalCount = 0;
                for (OrderInputPackageDo packageDo : packageDoList) {
                    OrderInputExcelExportPackageInfoVo exportPackageInfoVo = new OrderInputExcelExportPackageInfoVo();
                    BeanUtils.copyProperties(packageDo, exportPackageInfoVo);
                    pacakgeCount = pacakgeCount + packageDo.getPackageCount();
                    LambdaQueryWrapper<OrderInputProductDo> productWrapper = new LambdaQueryWrapper<>();
                    productWrapper.eq(OrderInputProductDo::getPackageId, packageDo.getId());
                    List<OrderInputProductDo> productDoList = orderInputProductDao.selectList(productWrapper);
                    if (productDoList == null || productDoList.size() < 1) continue;
                    List<OrderInputExcelExportProductInfoVo> excelExportProductInfoVoList = new ArrayList<>();
                    for (OrderInputProductDo productDo : productDoList) {
                        OrderInputExcelExportProductInfoVo exportProductInfoVo = new OrderInputExcelExportProductInfoVo();
                        ProductInfoDo productInfoDo = productInfoDao.selectById(productDo.getProductId());
                        if (productInfoDo != null) {
                            exportProductInfoVo.setCommoditySku(productInfoDo.getCommoditySku());
                        }
                        exportProductInfoVo.setCount(productDo.getCount() * packageDo.getPackageCount());
                        exportProductInfoVo.setReceiveCount(productDo.getReceiveCount());
                        exportProductInfoVo.setBrokenCount(productDo.getBrokenCount());
                        totalCount = totalCount + packageDo.getPackageCount() * productDo.getCount();
                        excelExportProductInfoVoList.add(exportProductInfoVo);
                    }
                    exportPackageInfoVo.setProductInfoVoList(excelExportProductInfoVoList);
                    excelExportPackageInfoVoList.add(exportPackageInfoVo);
                }
                excelExportVo.setPackageInfoVoList(excelExportPackageInfoVoList);
                excelExportVoList.add(excelExportVo);
            }
        }

        try {
            ExcelUtils.exportExcel(excelExportVoList, OrderInputExcelExportInfoVo.class, "入库订单", new ExportParams(), response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private void handlerInputFeeToRedis(OrderInputDo orderInputDo) {

        double totalVolume = 0;

        LambdaQueryWrapper<OrderInputPackageDo> packageDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        packageDoLambdaQueryWrapper.eq(OrderInputPackageDo::getOrderInputId, orderInputDo.getId());
        List<OrderInputPackageDo> orderInputPackageDos = orderInputPackageDao.selectList(packageDoLambdaQueryWrapper);
        if (!CollectionUtils.isEmpty(orderInputPackageDos)) {
            for (OrderInputPackageDo orderInputPackageDo : orderInputPackageDos) {
                LambdaQueryWrapper<OrderInputProductDo> productDoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                productDoLambdaQueryWrapper.eq(OrderInputProductDo::getPackageId, orderInputPackageDo.getId());
                List<OrderInputProductDo> orderInputProductDos = orderInputProductDao.selectList(productDoLambdaQueryWrapper);
                if (!CollectionUtils.isEmpty(orderInputProductDos)) {
                    for (OrderInputProductDo orderInputProductDo : orderInputProductDos) {
                        ProductInfoDo productInfoDo = productInfoDao.selectById(orderInputProductDo.getProductId());
                        if (productInfoDo == null) continue;
                        totalVolume += productInfoDo.getLength() * productInfoDo.getWidth() * productInfoDo.getHeight() / 1000000 * (orderInputProductDo.getBrokenCount() + orderInputProductDo.getReceiveCount()) * orderInputPackageDo.getPackageCount().doubleValue();
                    }
                }
            }
        }
        StorageDo storageDo = storageDao.selectById(orderInputDo.getStorageId());
        if (storageDo == null) return;

        double totalFee = storageDo.getDayPrice() * totalVolume;
        if (totalFee == 0) return;
        redisTemplate.opsForValue().set("sevenFreeInputFee:" + orderInputDo.getCompanyId() + "_" + orderInputDo.getShopId() + "_" + UUID.randomUUID().toString(), totalFee, 7, TimeUnit.DAYS);
    }

    @Override
    public Long openApiAdd(OrderInputOpenApiAddReq req, Long userId, Long companyId) {
        //校验余额不足
//        sufficientFundsCheck(companyId);

        OrderInputDo entityDo = new OrderInputDo();
        BeanUtils.copyProperties(req, entityDo);
        entityDo.setCompanyId(companyId);
        entityDo.setStatus(DicBusinessItemConstant.inCreateState);
        if (req.getFbaTurn() == 1) {
            //操作附件
            fileService.uploadFile(req.getFbaFileId());
        }
        if (req.getSendType() == 1) {
            //操作附件
            fileService.uploadFile(req.getClearFileId());
        }
        handlerAddBefore(entityDo, userId);
        dao.insert(entityDo);

        //操作日志
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_CREATE_INPUT, entityDo.getId(), userId, 2);
//        addOperateRecord(entityDo, userId);

        double volume = 0F;
        double weight = 0F;

        if (!CollectionUtils.isEmpty(req.getPackageList())) {
            for (OrderInputPackageAdd packageAdd : req.getPackageList()) {
                OrderInputPackageDo packageDo = new OrderInputPackageDo();
                packageDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                packageDo.setPackageLenght(packageAdd.getPackageLenght());
                packageDo.setPackageWidth(packageAdd.getPackageWidth());
                packageDo.setPackageHeight(packageAdd.getPackageHeight());
                packageDo.setPackageWeight(packageAdd.getPackageWeight());
                packageDo.setPackageCount(packageAdd.getPackageCount());
                packageDo.setOrderInputId(entityDo.getId());
                orderInputPackageDao.insert(packageDo);
                if (!CollectionUtils.isEmpty(packageAdd.getProductDetailList())) {
                    for (OrderInputProductAdd productAdd : packageAdd.getProductDetailList()) {
                        if (productAdd.getProductId() == null || productAdd.getProductId() == 0) {
                            if (StringUtils.isBlank(productAdd.getProductSku())) {
                                throw new BizExceptionI18(SysConstant.NO_SKU_PLS_CHECK);

                            }
                            productAdd.setProductId(getProductId(productAdd.getProductSku(), entityDo.getCompanyId()));
                        }
                        OrderInputProductDo productDo = new OrderInputProductDo();
                        productDo.setOrderInputId(entityDo.getId());
                        productDo.setPackageId(packageDo.getId());
                        productDo.setProductId(productAdd.getProductId());
                        productDo.setCount(productAdd.getCount());
                        orderInputProductDao.insert(productDo);
                        ProductInfoDo productInfoDo = productInfoDao.selectById(productDo.getProductId());
                        if (productInfoDo != null) {
                            volume += productInfoDo.getHeight() * productInfoDo.getWidth() * productInfoDo.getLength() * productDo.getCount() * packageDo.getPackageCount();
                            weight += productInfoDo.getWeight() * productDo.getCount() * packageDo.getPackageCount();
                        }
                    }
                } else {
                    volume += packageDo.getPackageLenght() * packageDo.getPackageWidth() * packageDo.getPackageHeight() * packageDo.getPackageCount();
                    weight += packageDo.getPackageWeight() * packageDo.getPackageCount();
                }
            }
        }
        entityDo.setVolume(new BigDecimal(volume / 1000000).setScale(2, RoundingMode.HALF_UP).floatValue());
        entityDo.setWeight(new BigDecimal(weight).setScale(2, RoundingMode.HALF_UP).floatValue());
        String companyCode = "";
        CompanyDo companyDo = companyDao.selectById(companyId);
        if (companyDo != null)
            companyCode = companyDo.getCompanyCode();
        entityDo.setOrderInputNumber(OrderCodeUtil.getOrderInputNumber(companyCode, entityDo.getId()));
        dao.updateById(entityDo);
//        threadPoolTaskExecutor.execute(() -> {
//            mailSenderService.sendEmail("您有新的入库申请单需要审核", entityDo.getCompanyId() +
//                    "申请了入库单，请尽快审核,备注：" + entityDo.getTips(), SysConstant.cloudkintEmail);
//        });
        return entityDo.getId();
    }

    @Override
    public Long openApiUpdate(OrderInputOpenApiUpdateReq req, Long userId) {
        OrderInputDo entityDo = dao.selectById(req.getId());
        if (req.getFbaFileId() == null) req.setFbaFileId(0L);
        if (entityDo.getFbaFileId() == null) entityDo.setFbaFileId(0L);
        try {
            if (req.getFbaTurn() == 1 && !req.getFbaFileId().equals(entityDo.getFbaFileId())) {
                fileService.deleteFile(entityDo.getFbaFileId());
                fileService.uploadFile2(req.getFbaFileId(), entityDo.getFbaFileId());
            }
            if (req.getSendType() == 1 && !req.getClearFileId().equals(entityDo.getClearFileId())) {
                fileService.deleteFile(entityDo.getClearFileId());
                fileService.uploadFile2(req.getClearFileId(), entityDo.getClearFileId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        BeanUtils.copyProperties(req, entityDo);
        handlerUpdateBefore(entityDo, userId);
        dao.updateById(entityDo);

        LambdaQueryWrapper<OrderInputPackageDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderInputPackageDo::getOrderInputId, entityDo.getId());
        orderInputPackageDao.delete(wrapper);

        LambdaQueryWrapper<OrderInputProductDo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(OrderInputProductDo::getOrderInputId, entityDo.getId());
        orderInputProductDao.delete(productWrapper);

        Float volume = 0F;
        Float weight = 0F;

        if (!CollectionUtils.isEmpty(req.getPackageList())) {
            for (OrderInputPackageAdd packageAdd : req.getPackageList()) {
                OrderInputPackageDo packageDo = new OrderInputPackageDo();
                packageDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
                packageDo.setPackageLenght(packageAdd.getPackageLenght());
                packageDo.setPackageWidth(packageAdd.getPackageWidth());
                packageDo.setPackageHeight(packageAdd.getPackageHeight());
                packageDo.setPackageWeight(packageAdd.getPackageWeight());
                packageDo.setPackageCount(packageAdd.getPackageCount());
                packageDo.setOrderInputId(entityDo.getId());
                orderInputPackageDao.insert(packageDo);

                if (!CollectionUtils.isEmpty(packageAdd.getProductList())) {
                    for (OrderInputProductAdd productAdd : packageAdd.getProductList()) {
                        OrderInputProductDo productDo = new OrderInputProductDo();
                        productDo.setOrderInputId(entityDo.getId());
                        productDo.setPackageId(packageDo.getId());
                        if (productAdd.getProductId() == null || productAdd.getProductId() == 0) {
                            if (StringUtils.isBlank(productAdd.getProductSku())) {
                                throw new BizExceptionI18(SysConstant.NO_SKU_PLS_CHECK);
                            }
                            productAdd.setProductId(getProductId(productAdd.getProductSku(), entityDo.getCompanyId()));
                        }
                        productDo.setProductId(productAdd.getProductId());
                        productDo.setCount(productAdd.getCount());
                        orderInputProductDao.insert(productDo);

                        ProductInfoDo productInfoDo = productInfoDao.selectById(productDo.getProductId());
                        if (productInfoDo != null) {
                            volume += productInfoDo.getHeight() * productInfoDo.getWidth() * productInfoDo.getLength() * productDo.getCount() * packageDo.getPackageCount();
                            weight += productInfoDo.getWeight() * productDo.getCount() * packageDo.getPackageCount();
                        }

                    }
                } else {
                    volume += packageDo.getPackageLenght() * packageDo.getPackageWidth() * packageDo.getPackageHeight() * packageDo.getPackageCount();
                    weight += packageDo.getPackageWeight() * packageDo.getPackageCount();
                }
            }
        }
        entityDo.setVolume(new BigDecimal(volume / 1000000).setScale(2, BigDecimal.ROUND_HALF_UP).floatValue());
        entityDo.setWeight(new BigDecimal(weight).setScale(2, BigDecimal.ROUND_HALF_UP).floatValue());
        dao.updateById(entityDo);
        operateRecordDao.operateAddRecord(SysConstant.OPERATE_UPDATE_INPUT_ORDER, entityDo.getId(), userId, 2);
        return entityDo.getId();
    }

    @Override
    public boolean openApiDelete(Long id, Long userId) {
        OrderInputDo entityDo = dao.selectById(id);
        handlerDeleteBefore(entityDo, userId);
        int result = dao.deleteById(id);
        //删除从表
        LambdaQueryWrapper<OrderInputPackageDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderInputPackageDo::getOrderInputId, id);
        orderInputPackageDao.delete(wrapper);

        LambdaQueryWrapper<OrderInputProductDo> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.eq(OrderInputProductDo::getOrderInputId, id);
        orderInputProductDao.delete(productWrapper);
        return result > 0;
    }


    /**
     * 新版下载产品标
     *
     * @param id
     * @param length
     * @param width
     * @param response
     */
    @Override
    public void printBarCodePdf(Map<String, String> map, Long id, int length, int width, HttpServletResponse response) {
        OrderInputDo inputDo = dao.selectById(id);
        if (inputDo == null) throw new BizExceptionI18(SysConstant.NO_ORDER_INFO);
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("order_input_id", id);
        OderInputDetailRes detailRes = detail(id);
        final int[] count = new int[1];
        if (detailRes.getPackageList() != null && detailRes.getPackageList().size() > 0) {
            detailRes.getPackageList().stream().forEach(packageBean -> {
                if (packageBean.getProductList() != null && packageBean.getProductList().size() > 0) {
                    packageBean.getProductList().stream().forEach(product -> {
                        count[0] = count[0] + packageBean.getCount() * product.getCount();
                    });
                }
            });
        }
        if (count[0] >= 5000) {
            throw new BizExceptionI18(SysConstant.PLS_ADMIN_OVERSIZE);
        }
        String name = inputDo.getOrderInputNumber() + "_" + TimeUtils.getCurrentDateFormat("HHmmss");
        if (length == 210 && width == 297) {
            //a4打印 一行三个
            BarCodePdfUtils.orderInputPrintA4(map, detailRes, name, response);
        } else {
            //其他纸张类型 一张一个
            BarCodePdfUtils.orderInputPrint(map, detailRes, length, width, name, response);
        }
    }

    @Override
    public double getOrderInputUnitCost(Long orderId) {
        //获取一个订单的总体积
        float vol = this.getTotalVolByOrderId(orderId);
        //单位成本
        if (vol == 0f) {
            return 0d;
        }

        //计算单位入库成本
        //根据订单id 获取t_header_price_item 表中的费用
//        List<HeaderPriceItemDo> headerPriceItemDoList = headerPriceItemService.getBaseMapper().selectList(new LambdaQueryWrapper<HeaderPriceItemDo>()
//                .eq(HeaderPriceItemDo::getOrderInputId, orderId));
        HeaderContainerOrderDo containerOrderDo = headerContainerOrderDao.selectOne(new LambdaQueryWrapper<HeaderContainerOrderDo>()
                .eq(HeaderContainerOrderDo::getFirstVesselOrderId, orderId));
        if (containerOrderDo == null) {
            return 0d;
        }
        HeaderContainerDo headerContainerDo = headerContainerDao.selectById(containerOrderDo.getHeaderContainerId());
        if (headerContainerDo == null) {
            return 0d;
        }

        ManageBillDo billDo = null;
        if (containerOrderDo.getBillId() != null) {
            billDo = manageBillDao.selectById(containerOrderDo.getBillId());
        } else {
            billDo = manageBillDao.getBillByHeaderId(headerContainerDo.getId());
        }
        if (billDo == null) {
            return 0d;
        }
        //计算这个账单下有多少订单 ，按体积均摊
        List<Long> orderIds;
        ManageHeaderRateDo headerRateDo;
        if (billDo.getBatch() == 0) {
            //散货 或者单个柜子录入
            orderIds = headerContainerOrderDao.selectList(new LambdaQueryWrapper<HeaderContainerOrderDo>()
                    .eq(HeaderContainerOrderDo::getBillId, billDo.getId())).stream().map(HeaderContainerOrderDo::getFirstVesselOrderId).collect(Collectors.toList());
            //汇率
            headerRateDo = manageHeaderRateDao.selectOne(new LambdaQueryWrapper<ManageHeaderRateDo>()
                    .eq(ManageHeaderRateDo::getHeaderId, headerContainerDo.getId()).eq(ManageHeaderRateDo::getType, "header"));
        } else {
            //批量整柜录入
            orderIds = dao.getOrderIdByBillId(billDo.getId());
            headerRateDo = manageHeaderRateDao.selectOne(new LambdaQueryWrapper<ManageHeaderRateDo>()
                    .eq(ManageHeaderRateDo::getHeaderId, billDo.getId()).eq(ManageHeaderRateDo::getType, "bill"));
        }
        if (headerRateDo == null) {
            log.error("订单id:" + orderId + "未匹配到汇率");
            return 0d;
        }
        float totalVol = 0f;
        //计算账单下商品总体积
        for (Long id : orderIds) {
            totalVol = MathUtils.add(totalVol, this.getTotalVolByOrderId(id));
        }
        if (totalVol == 0f) {
            return 0d;
        }
        //账单的 项目金额
        List<ManageHeaderPriceItemDo> headerPriceItemDoList = manageHeaderPriceItemDao.selectList(new LambdaQueryWrapper<ManageHeaderPriceItemDo>()
                .eq(ManageHeaderPriceItemDo::getBillId, billDo.getId())
                .eq(ManageHeaderPriceItemDo::getType, "beginBill"));
        //转换成美金
        double cost = 0;
        for (ManageHeaderPriceItemDo headerPriceItemDo : headerPriceItemDoList) {
            if (DicBusinessItemConstant.currency_rmb.equals(headerPriceItemDo.getCurrencyType())) {
                //RMB
                cost = MathUtils.add(cost, MathUtils.div(headerPriceItemDo.getPrice() + headerPriceItemDo.getTax(), headerRateDo.getUsdRate()));
            } else if ((DicBusinessItemConstant.currency_jpy).equals(headerPriceItemDo.getCurrencyType())) {
                //JPY
                cost = MathUtils.add(cost, MathUtils.div(MathUtils.mul(headerPriceItemDo.getPrice() + headerPriceItemDo.getTax(), headerRateDo.getJpyRate()), headerRateDo.getUsdRate()));
            } else {
                //美金
                cost = MathUtils.add(cost, headerPriceItemDo.getPrice() + headerPriceItemDo.getTax());
            }
        }

        //按体积 均摊这个订单的费用
        cost = MathUtils.mul(cost, MathUtils.div(vol, totalVol));
        double unitCost = MathUtils.div(20, cost, MathUtils.numberFormat(vol + ""));
        //返回这条入库单的单位费用
        return unitCost;
    }

    @Override
    public Map<String, Long> batchMatchSkuId(OrderInputOpenApiMatchProductIdReq req, Long companyId) {
        //获取所有的产品
        Set<String> skuList = req.getSkuList();
        Map<String, Long> skuMap = new HashMap<>();
        if (CollUtil.isNotEmpty(skuList)) {
            Map<String, Long> skuMao = productInfoDao.getProductSkuAndIdList(new ArrayList<>(skuList), "commodity_sku", companyId)
                    .stream().collect(Collectors.toMap(ProductSkuAndIdDto::getSku, ProductSkuAndIdDto::getId, (v1, v2) -> v2));
            skuMap.putAll(skuMao);
            List<String> leftStorageSkuList = skuList.stream().filter(sku -> !skuMao.containsKey(sku)).collect(Collectors.toList());
            Map<String, Long> storageSkuMap;
            if (CollUtil.isNotEmpty(leftStorageSkuList)) {
                storageSkuMap = productInfoDao.getProductSkuAndIdList(leftStorageSkuList, "storage_sku", companyId)
                        .stream().collect(Collectors.toMap(ProductSkuAndIdDto::getSku, ProductSkuAndIdDto::getId, (v1, v2) -> v2));
                skuMap.putAll(storageSkuMap);
            } else {
                storageSkuMap = new HashMap<>();
            }
            List<String> leftSubSkuMap = leftStorageSkuList.stream().filter(sku -> !storageSkuMap.containsKey(sku)).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(leftSubSkuMap)) {
                Map<String, Long> subSkuMap = productInfoDao.getSubProductSkuAndIdList(leftStorageSkuList, companyId).stream().collect(Collectors.toMap(ProductSkuAndIdDto::getSku, ProductSkuAndIdDto::getId, (v1, v2) -> v2));
                skuMap.putAll(subSkuMap);
            }
        }
        return skuMap;
    }


    /**
     * 计算一个 订单下的总体积
     *
     * @param orderId
     * @return
     */
    public float getTotalVolByOrderId(Long orderId) {
        OrderInputDo et = dao.selectById(orderId);
        if (et == null) {
            return 0f;
        }
        List<OrderInputProductDo> productDoList = orderInputProductDao.selectList(new LambdaQueryWrapper<OrderInputProductDo>().eq(OrderInputProductDo::getOrderInputId, orderId));
        Map<Long, List<OrderInputProductDo>> listMap = productDoList.stream().collect(Collectors.groupingBy(OrderInputProductDo::getProductId));
        Set<Long> productIdList = listMap.keySet();
        float vol = 0f;//总体积
        for (Long productId : productIdList) {
            List<OrderInputProductDo> list = listMap.get(productId);

            ProductInfoDo productInfoDo = productInfoDao.selectById(productId);
            if (productInfoDo == null) {
                continue;
            }
            float singleVol = productInfoDo.getHeight() * productInfoDo.getWidth() * productInfoDo.getLength();
            //如果订单已上架 则按照 上架的数量计算
            int count = 0;
            if (DicBusinessItemConstant.putaway.equals(et.getStatus())) {
                count = list.stream().mapToInt(OrderInputProductDo::getReceiveCount).sum() + list.stream().mapToInt(OrderInputProductDo::getBrokenCount).sum();
            } else {
                count = list.stream().mapToInt(OrderInputProductDo::getCount).sum();

            }
            vol = MathUtils.calcFloatValue(vol, MathUtils.calcFloatValue(singleVol, count, "multiply"), "add");
        }
        return vol;
    }

}
